﻿// VectorComputation.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
// 
#ifdef   _X86   
#pragma message("_X86 macro activated!")   
#endif

#include "EulerAngle.h"
#include "VectorInformation.h"
#include "MatrixInformation.h"
#include "TranslationMatrixInformation.h"
inline VOID Start()
{
    cout << endl << " ----------------------------------------  The program starts running   ----------------------------------------  " << endl;
}
inline VOID End()
{
    cout << endl << " ----------------------------------------   The program ends running    ---------------------------------------- " << endl;
}


VOID TestVector() {
    // 向量与标量的(+-*/)运算
    VectorInformation ved;
    ved.ShowVectorInformation();

    VectorInformation ved1(10, 20, 30);
    VectorInformation ved2 = -ved1;
    ved1.ShowVectorInformation();
    ved2.ShowVectorInformation();
    cout << "square:ved1=" << ved1.SquareVectorDescription() << endl;

    ved1.ZeroVectorDescription();
    ved1.ShowVectorInformation();

    VectorInformation ved4(5, -4, 7);
    cout << "square:ved4=" << ved4.SquareVectorDescription() << endl;
    VectorInformation ved5(-5, 0, 0.4);
    VectorInformation ved6 = ved5 * -3;
    ved6.ShowVectorInformation();
    ved5 *= -3;
    ved5.ShowVectorInformation();
    VectorInformation ved7(4.7, -6, 8);
    VectorInformation ved8 = ved7 / 2;
    ved8.ShowVectorInformation();
    VectorInformation ved9(1, 2, 3);
    VectorInformation ved10 = 2 * ved9;

    ved10.ShowVectorInformation();

    // 向量的标准化运算
    VectorInformation ved11(12, -5, 0);
    ved11.Normalize();
    ved11.ShowVectorInformation();


    // 向量与向量的加减运算
    VectorInformation ved12(10, 2, 3);
    VectorInformation ved13(4, 5, 6);

    VectorInformation ved14 = ved12 - ved13;
    VectorInformation ved15 = ved12 + ved13;
    ved14.ShowVectorInformation();
    ved15.ShowVectorInformation();
    ved12 -= ved13;
    ved12.ShowVectorInformation();
    ved12 += ved13;
    ved12.ShowVectorInformation();


    // 计算两个向量点的距离
    VectorInformation ved16(5, 0, 0);
    VectorInformation ved17(-1, 8, 0);
    cout << "Distance:" << GetDistanceBetweenTwoVectorPoints(ved16, ved17) << endl;

    // 向量点乘
    VectorInformation ved18(3, -2, 7);
    VectorInformation ved19(0, 4, -1);

    double multiplyPointer = ved18 * ved19;
    cout << "multiplyPointer:" << multiplyPointer << endl;
    // 计算余铉角
    double cos = GetCosAngle(ved18, ved19);
    cout << "cos:" << cos << endl;
    // 计算向量叉乘
    VectorInformation ved20(1, 3, 4);
    VectorInformation ved21(2, -5, 8);
    VectorInformation cm = CrossMultiply(ved20, ved21);
    cout << "CrossMultiply=";
    cm.ShowVectorInformation();
    cout << endl;
}

// 矩阵与向量的运算
VOID TestOperationMatrix()
{
    MatrixInformation matrixInfo0;
    cout << endl << "原矩阵0:" << endl;
    matrixInfo0.ShowMatrixInformation();
    double r0[] = { 1, 2, 3 };
    matrixInfo0.SetMatrixRowData(MatrixInformation::INDEX0, r0);
    cout << endl << "设置第1行的数据:" << endl;
    matrixInfo0.ShowMatrixInformation();

    double c1[] = { 7, 8, 9 };
    matrixInfo0.SetMatrixColData(MatrixInformation::INDEX2, c1);
    cout << endl << "设置第3列的数据:" << endl;
    matrixInfo0.ShowMatrixInformation();



    // 矩阵乘以矩阵的运算
    double data1[][3] = { {1,-5,3},{0,-2,6},{7,2,-4} };
    double data2[][3] = { {-8,6,1},{7,0,-3},{2,4,5} };
    MatrixInformation matrixInfor1(data1);
    MatrixInformation matrixInfor2(data2);
    MatrixInformation matrixInfor3 = matrixInfor1 * matrixInfor2;
    cout << endl << "原矩阵1:" << endl;
    matrixInfor1.ShowMatrixInformation();
    cout << endl << "原矩阵2:" << endl;
    matrixInfor2.ShowMatrixInformation();
    cout << endl << "原矩阵1*原矩阵2=新矩阵:" << endl;
    matrixInfor3.ShowMatrixInformation();

    // 向量乘以矩阵
    double data3[][3] = { {-2,0,3},{5,7,-6},{1,-4,2} };
    MatrixInformation matrixInfo5(data3);
    VectorInformation veci(3, -1, 4);
    cout << endl << "原矩阵5:" << endl;
    matrixInfo5.ShowMatrixInformation();
    cout << endl << "原向量:" << endl;
    veci.ShowVectorInformation();

    VectorInformation mulVecMatrix = veci * matrixInfo5;
    cout << endl << "原向量*原矩阵5=新向量:" << endl;
    mulVecMatrix.ShowVectorInformation();
}
// 测试矩阵旋转
VOID TestRotationMatrix()
{
    // 创建一个向量
    VectorInformation vecBeforeRotation(10, 0, 0), vecAfterRotation;
    vecBeforeRotation.ShowVectorInformation();
    // 创建一个矩阵
    MatrixInformation matrix;
    cout << endl << "原矩阵:" << endl;
    matrix.ShowMatrixInformation();
    // 沿着Z轴旋转矩阵90度
    matrix.RotationMatrix(ROTATE_TYPE::ROTATE_Z, RadiansToAngles(90));
    cout << endl << "沿着Z轴旋转矩阵90度:" << endl;
    matrix.ShowMatrixInformation();
    vecAfterRotation = vecBeforeRotation * matrix;
    cout << endl << "旋转后的向量:" << endl;
    vecAfterRotation.ShowVectorInformation();

    
    matrix.RotationMatrix(ROTATE_TYPE::ROTATE_Z, RadiansToAngles(180));
    cout << endl << "沿着Z轴旋转矩阵180度:" << endl;
    matrix.ShowMatrixInformation();
    vecAfterRotation = vecBeforeRotation * matrix;
    cout << endl << "旋转后的向量:" << endl;
    vecAfterRotation.ShowVectorInformation();


    // 沿着X轴旋转矩阵-22度
    matrix.RotationMatrix(ROTATE_TYPE::ROTATE_X, RadiansToAngles(-22));
    cout << endl << "沿着X轴旋转矩阵-22度:" << endl;
    matrix.ShowMatrixInformation();

    matrix.RotationMatrix(ROTATE_TYPE::ROTATE_Y, RadiansToAngles(30));
    cout << endl << "沿着Y轴旋转矩阵30度:" << endl;
    matrix.ShowMatrixInformation();

}
// 测试矩阵缩放
VOID TestSaclingMatrix()
{
    // 创建一个矩阵
    MatrixInformation matrix;
    // 矩阵缩放
    VectorInformation vecBefore(10, 20, 30), vecAfter, vecVar(1, 2, 3);
    cout << endl << "原向量:" << endl;
    vecBefore.ShowVectorInformation();
    cout << endl << "原矩阵:" << endl;
    matrix.ShowMatrixInformation();

    matrix.SaclingMatrix(vecVar);
    cout << endl << "缩放后矩阵:" << endl;
    matrix.ShowMatrixInformation();

    vecAfter = vecBefore* matrix;
    cout << endl << "缩放后向量:" << endl;
    vecAfter.ShowVectorInformation();
}
// 测试矩阵投影
VOID TestProjectionMatrix()
{    
    // 创建两个向量
    VectorInformation vecBefore(10, 20, 30), vecAfter;
    cout << endl << "原向量:" << endl;
    vecBefore.ShowVectorInformation();
    // 创建一个矩阵
    MatrixInformation matrix;
    cout << endl << "原矩阵:" << endl;
    matrix.ShowMatrixInformation();

    // 创建向量用于投影矩阵,投影到xy平面
    VectorInformation vecInfo(0,0,1);
    matrix.ProjectionMatrix(vecInfo);
    cout << endl << "投影到xy平面的矩阵:" << endl;
    matrix.ShowMatrixInformation();
    // 投影vecBefore到xy平面
    vecAfter = vecBefore * matrix;
    cout << endl << "投影后的向量:" << endl;
    vecAfter.ShowVectorInformation();
}
// 测试矩阵镜像
VOID TestMatrixImage()
{
    // 创建两个向量
    VectorInformation vecBefore(10, 20, 30), vecAfter;
    cout << endl << "原向量:" << endl;
    vecBefore.ShowVectorInformation();
    // 创建一个矩阵
    MatrixInformation matrix;
    // X轴镜像
    matrix.MatrixImageXYZ(ROTATE_TYPE::ROTATE_X);
    vecAfter = vecBefore * matrix;
    cout << endl << "X轴镜像后 向量:" << endl;
    vecAfter.ShowVectorInformation();
    // Y轴镜像
    matrix.MatrixImageXYZ(ROTATE_TYPE::ROTATE_Y);
    vecAfter = vecBefore * matrix;
    cout << endl << "Y轴镜像后 向量:" << endl;
    vecAfter.ShowVectorInformation();
    // Z轴镜像
    matrix.MatrixImageXYZ(ROTATE_TYPE::ROTATE_Z);
    vecAfter = vecBefore * matrix;
    cout << endl << "Z轴镜像后 向量:" << endl;
    vecAfter.ShowVectorInformation();
    // 任意轴镜像
    VectorInformation v1(0, 0, 1), v2;
    matrix.ArbitraryMatrixImage(v1);
    v2 = vecBefore * matrix;
    cout << endl << "任意轴镜像后 向量:" << endl;
    v2.ShowVectorInformation();
}
// 测试矩阵切变
VOID TestMatrixShear()
{
    // 创建两个向量
    VectorInformation vecBefore(10, 20, 30), vecAfter;
    cout << endl << "原向量:" << endl;
    vecBefore.ShowVectorInformation();

    MatrixInformation matrix;
    cout << endl << "原矩阵:" << endl;
    matrix.ShowMatrixInformation();

    // x轴切变y轴和z轴
    matrix.MatrixShear(ROTATE_TYPE::ROTATE_X, 1, 2);
    cout << endl << "x轴切变后的矩阵:" << endl;
    matrix.ShowMatrixInformation();

    vecAfter = vecBefore * matrix;
    cout << endl << "x轴切变后的向量:" << endl;
    vecAfter.ShowVectorInformation();
}

// 测试矩阵的逆
VOID TestInverseOfMatrix() 
{
    // 计算矩阵的逆
    double data[MATRIX_ROW_COUNT][MATRIX_COL_COUNT] = { {-4,-3,3},{0,2,-2},{1,4,-1} };
    // 声明一个矩阵,和一个矩阵的逆
    MatrixInformation matrix1(data);
    cout << endl << "原矩阵:" << endl;
    matrix1.ShowMatrixInformation();

    cout << endl << "原矩阵的逆:" << endl;
    MatrixInformation InvMatrix1 = InverseOfMatrix(matrix1);
    InvMatrix1.ShowMatrixInformation();


    // 矩阵的逆的逆等于原先的矩阵
    cout << endl << "原矩阵的逆的逆:" << endl;
    MatrixInformation InvMatrix2 = InverseOfMatrix(InvMatrix1);
    InvMatrix2.ShowMatrixInformation();

    // 原矩阵*原矩阵的逆是一个单位矩阵
    MatrixInformation NewMatrix1 = matrix1 * InvMatrix1;
    cout << endl << "原矩阵*原矩阵的逆=单位矩阵:" << endl;
    NewMatrix1.ShowMatrixInformation();
}
// 测试矩阵行列式
VOID TestDeterminantMatrix()
{
    double arrayMatrix[][MATRIX_COL_COUNT] = { {3,-2,0},{1,4,-3},{-1,0,2} };
    MatrixInformation matrix(arrayMatrix);
    double result = matrix.DeterminantMatrix();
    cout << "矩阵:" << endl;
    matrix.ShowMatrixInformation();
    cout << "矩阵的行列式为:" << result << endl;
}
// 测试单位矩阵
VOID TestIdentityMatrix()
{
    MatrixInformation NewMatrix2;
    cout << endl << "原矩阵:" << endl;
    NewMatrix2.ShowMatrixInformation();
    cout << endl << "将矩阵转换成单位矩阵:" << endl;
    NewMatrix2.ConvertToIdentityMatrix();
    NewMatrix2.ShowMatrixInformation();
}
// 测试平移矩阵
VOID TestTranslationMatrix()
{
    // 将平移矩阵转换成单位矩阵并使用向量对平移部分赋值
    TranslationMatrixInformation translation;
    cout << endl << "平移矩阵:" << endl;
    translation.ShowTranslationMatrixInformation();

    cout << endl << "平移矩阵转换成单位矩阵:" << endl;
    translation.ConvertToIdentityMatrix();
    translation.ShowTranslationMatrixInformation();


    cout << endl << "清零平移部分:" << endl;
    translation.ZeroTranslation();
    translation.ShowTranslationMatrixInformation();

    cout << endl << "平移矩阵清零:" << endl;
    translation.ZeroTranslationMatrixData();
    translation.ShowTranslationMatrixInformation();


    cout << endl << "平移矩阵转换成单位矩阵并设置平移:" << endl;
    VectorInformation vec(17, 52, 93);
    translation.ConvertToIdentityMatrixSetTranslation(vec);
    translation.ShowTranslationMatrixInformation();

    cout << endl << "单位矩阵:" << endl;
    translation.ConvertToIdentityMatrix();
    translation.ShowTranslationMatrixInformation();

    cout << endl << "获取平移矩阵平移部分的向量:" << endl;
    VectorInformation v1;
    v1 = translation.GetTranslation();
    v1.ShowVectorInformation();


    MatrixInformation m;
    m.RotationMatrix(ROTATE_TYPE::ROTATE_Y, 90);
    m.ShowMatrixInformation();
}

// 测试矩阵坐标系变换
VOID TestCoordinateMatrix()
{
    // 定义矩阵数据,初始化矩阵
    double data[][MATRIX_COL_COUNT] = { {0.866f,0,-0.5f} ,{0.0f,1.0f,0.0f} ,{0.5f,0, 0.866f} };
    MatrixInformation matrix1(data);
    // 定义并初始化向量
    VectorInformation vector1(10, 20, 30),vector2;

    cout << endl << "《矩阵数据初始化矩阵》惯性坐标系转换为物体坐标系:" << endl;
    vector2 = matrix1.InertialToObject(vector1);
    vector2.ShowVectorInformation();

    cout << endl << "《矩阵数据初始化矩阵》物体坐标系转换为惯性坐标系:" << endl;
    vector2 = matrix1.ObjectToInertial(vector1);
    vector2.ShowVectorInformation();

}
// 测试欧拉角坐标系变换
VOID TestCoordinateEulerAngle()
{
    // 声明一个矩阵
    MatrixInformation matrix1;
    // 时殷弘欧拉角初始化矩阵
    EulerAngle eulerAngle(RadiansToAngles(30), 0, 0);
    matrix1.SetEulerAngle(eulerAngle);
    // 定义并初始化向量
    VectorInformation vector1(10, 20, 30), vector2;

    cout << endl << "《欧拉角初始化矩阵》惯性坐标系转换为物体坐标系:" << endl;
    vector2 = matrix1.InertialToObject(vector1);
    vector2.ShowVectorInformation();

    cout << endl << "《欧拉角初始化矩阵》物体坐标系转换为惯性坐标系:" << endl;
    vector2 = matrix1.ObjectToInertial(vector1);
    vector2.ShowVectorInformation();

}

int main()
{
    Start();
    // 向量类功能测试
    // TestVector();
    // 矩阵类功能测试与向量的运算
    // TestOperationMatrix();
    // // 测试矩阵旋转
    // TestRotationMatrix();
    // // 测试矩阵缩放
    // TestSaclingMatrix();
    // // 测试矩阵投影
    // TestProjectionMatrix();
    // // 测试矩阵镜像
    // TestMatrixImage();
    // // 测试矩阵行列式
    // TestDeterminantMatrix();

    // // 测试矩阵切变
    // TestMatrixShear();
    // // 测试单位矩阵
    // TestIdentityMatrix();
    // // 测试矩阵的逆
    // TestInverseOfMatrix();
    // // 测试使用矩阵数据初始化矩阵进行坐标系变换
    TestCoordinateMatrix();
    // // 测试使用欧拉角初始化矩阵进行坐标系变换
    TestCoordinateEulerAngle();
    End();
}
